通俗理解: 通过与自身有关联的表数据,查询自身表数据
跨多张表查询自身的数据的前提是,这多张表必须有关联
通过 .filter(xxx__xxx='xxx') 实现
1.表的结构
# models.py
from django.db import models
# 书
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name='书名')
publish_date = models.DateField(auto_now_add=True, verbose_name='出版日期')
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格')
memo = models.TextField(null=True, verbose_name='说明')
# 创建外键,关联publish
publisher = models.ForeignKey(to='Publisher', verbose_name='出版社')
# 创建多对多关联author
author = models.ManyToManyField(to='Author', verbose_name='作者')
def __str__(self):
return self.title
class Meta:
verbose_name = "书籍"
verbose_name_plural = verbose_name
# 出版社
class Publisher(models.Model):
name = models.CharField(max_length=32, verbose_name='出版社名称')
city = models.CharField(max_length=32, verbose_name='地址')
def __str__(self):
return self.name
class Meta:
verbose_name = "出版社"
verbose_name_plural = verbose_name
# 作者
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
phone = models.CharField(max_length=11, verbose_name='手机号码')
# 创建一对一关联authorDetail
detail = models.OneToOneField(to='AuthorDetail', verbose_name='详情')
def __str__(self):
return self.name
class Meta:
verbose_name = "作者"
verbose_name_plural = verbose_name
# 作者详情
class AuthorDetail(models.Model):
addr = models.CharField(max_length=64, verbose_name='地址')
email = models.EmailField(verbose_name='邮箱')
def __str__(self):
return self.addr
class Meta:
verbose_name = "作者详情"
verbose_name_plural = verbose_name
2.正向查询
- 语法: .filter(主表类的外键属性名__从表字段名='xxx', ……)
- 查询出书籍的 作者是yeung 的数据
book_list = Book.objects.filter(author__name='yeung')
- 查询出书籍的 作者是yeung,出版社是东莞出版社 的数据
book_list = Book.objects.filter(author__name='yeung').filter(publisher__name='东莞出版社')
# 等同于
book_list = Book.objects.filter(author__name='yeung', publisher__name='东莞出版社')
3. 反向查询
- 语法:
- 如果没有设置表类中外键属性的 related_name
- .filter(主表类名__主表字段名='xxx', ……)
# 查询出书名为西游记的作者
author = Author.objects.filter(book__title='西游记')
- 如果设置了表类中外键属性的 related_name
- .filter(related_name所设置的名字__主表字段名='xxx', ……)
# models.py
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name='书名')
publish_date = models.DateField(auto_now_add=True, verbose_name='出版日期')
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格')
memo = models.TextField(null=True, verbose_name='说明')
# 创建外键,关联publish
publisher = models.ForeignKey(to='Publisher', verbose_name='出版社')
# 创建多对多关联author
author = models.ManyToManyField(to='Author', verbose_name='作者', related_name='mf_book')
def __str__(self):
return self.title
class Meta:
verbose_name = "书籍"
verbose_name_plural = verbose_name
# 查询出书名为西游记的作者
author = Author.objects.filter(mf_book__title='西游记')